// Environment code for project cleaningRobot

import jason.asSyntax.*;
import jason.environment.*;
import jason.environment.grid.Location;

import java.awt.Point;
import java.util.logging.*;

public class MyEnv extends Environment {

	public static final Term bg = Literal.parseLiteral("burn(garb)");
	public static final Term gotoClosest = Literal.parseLiteral("gotoClosest");
	public static final Literal g1 = Literal.parseLiteral("garbage(r1)");
	
    private Logger logger = Logger.getLogger("cleaningRobot."+MyEnv.class.getName());

    
    Model model ;
    View view;
    
    /** Called before the MAS execution with the args informed in .mas2j */
    @Override
    public void init(String[] args) {
        model = new Model() ;
        view = new View(model);
        super.init(args);
        addPercept(Literal.parseLiteral("percept(demo)"));
    }

    public int GARBNumber() { // ham dem so rac hien co tren moi truong
		return model.countObjects(Model.GARB);
	}

	// ham add garb vao mang
	public Point[] garbArray() {
		Point[] array = new Point[model.countObjects(Model.GARB)];
		int garbCount = 0;
		for (int i = 0; i < model.getHeight(); i++)
			for (int j = 0; j < model.getWidth(); j++) {
				if (model.hasObject(Model.GARB, i, j)) {
					garbCount++;
					array[garbCount - 1] = new Point(i, j);
				}
			}
		return array;
	}

	
	public Point closestPoint() {
		Location r1Loc = model.getAgPos(0);
	
		Point closestGarb = new Point(garbArray()[0].x, garbArray()[0].y);
		for (int i = 0; i < garbArray().length; i++) {
			if (model.getDistance(r1Loc.x, r1Loc.y, garbArray()[i].x,
					garbArray()[i].y) < model.getDistance(r1Loc.x, r1Loc.y,
					closestGarb.x, closestGarb.y)) {
				closestGarb = garbArray()[i];
			}
		}
		return closestGarb;
	}

    
    @Override
    public boolean executeAction(String agName, Structure action) {
    	updatePercepts();
		logger.info(agName + " doing: " + action);
		try {
			if (action.getFunctor().equals("move_towards")) {
				int x = (int) ((NumberTerm) action.getTerm(0)).solve();// getTerm(0) => ??? 
				int y = (int) ((NumberTerm) action.getTerm(1)).solve();
				model.moveTowards(x, y);
				updatePercepts();
			} else if (action.equals(bg)) {   //   
				model.burnGarb();
				updatePercepts();
			} else if (action.equals(gotoClosest)) {
				model.moveTowards(this.closestPoint().x, this.closestPoint().y);
				updatePercepts();
			} else {
				updatePercepts();
				return false;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		updatePercepts();

		try {
			Thread.sleep(1000); // toc do xu ly hien thi nhanh or cham
		} catch (Exception e) {
		}
		informAgsEnvironmentChanged();  //  ????? 
		return true;
    }

    /** Called before the end of MAS execution */
    @Override
    public void stop() {
        super.stop();
    }
    
    void updatePercepts() {
		clearPercepts();

		Location r1Loc = model.getAgPos(0);
		Literal pos1 = Literal.parseLiteral("pos(r1," + (r1Loc.x) + ","
				+ r1Loc.y + ")");
		addPercept(pos1);
		if (model.hasObject(Model.GARB, r1Loc)) {
			addPercept(g1);
		}

	}
}
